﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ForrajeriaDB; //ESTE USING VA EN TODOS LOS ELEMENTOS DE ESTA CAPA
using System.Data;
using System.Data.SqlClient;

namespace ForrajeriaDAL
{
    public class EmpleadoDAL : AccesoDAL, InterfazDAL<EmpleadoMO>
    {
        #region VARIABLES PARA STORED QUE MANEJA EL OBJETO DE DAL

        private static string insert = "Empleado_INSERT";
        private static string delete = "Empleado_DELETE";
        private static string update = "Empleado_UPDATE";
        private static string all = "Empleado_GetALL";
        private static string getXID = "Empleado_GetByID";
        private static string allRegistrar = "Empleado_GetALLRegistrar";
        #endregion

        private SqlCommand cmd; //var de comando sql

        #region "Singleton"

        private static EmpleadoDAL instance;

        private EmpleadoDAL()
            : base()
        {

        }


        public static EmpleadoDAL Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new EmpleadoDAL();
                }
                return instance;
            }
        }

        #endregion

        #region Interfaz

        public List<EmpleadoMO> GetAll()
        {
            SqlDataReader reader =null;
            List<EmpleadoMO> lista=new List<EmpleadoMO>();
            try
            {
                cmd=new SqlCommand(all,getConexion());
                cmd.CommandType=CommandType.StoredProcedure;
                opencon();
                reader =cmd.ExecuteReader();
                while(reader.Read())
                {
                    EmpleadoMO aux = new EmpleadoMO();
                    //****************************Formar objeto aux**********************
                    aux.Codigo=int.Parse(reader["codigo"].ToString());

                    if (reader["apellido"].ToString() != null) //aca y cada vez que se compara contra un null de la base de datos se tiene q usar el DBNull.Value
                    { aux.Apellido=reader["apellido"].ToString();}
                    else{aux.Apellido="";}

                    if(reader["nombre"].ToString()!=null)
                    {aux.Nombre=reader["nombre"].ToString();}
                    else{aux.Nombre="";}

                    
                   
                    if(reader["telefono"].ToString()!=null)
                    {aux.Telefono=reader["telefono"].ToString();}
                    else{aux.Telefono="";}

                    aux.TipoDocumento=int.Parse(reader["tipoDocumento"].ToString());

                    aux.NroDocumento=int.Parse(reader["nroDocumento"].ToString());

                    aux.CodigoUsuario=int.Parse(reader["nroDocumento"].ToString());

                    
                    aux.Estado = reader["estado"].ToString();
                   

                     aux.Calle = reader["calle"].ToString();
                    

                    if (reader["nroCalle"].ToString() != null)
                    { aux.NroCalle = int.Parse(reader["nroCalle"].ToString()); }
                    else { aux.Calle = "0"; }

                    if (reader["piso"].ToString() != null)
                    { aux.Piso = reader["piso"].ToString(); }
                    else { aux.Piso = ""; }
                    
                    if (reader["dpto"].ToString() != null)
                    { aux.Dpto = reader["dpto"].ToString(); }
                    else { aux.Piso = ""; }


                    aux.Localidad = int.Parse(reader["id_localidad"].ToString());
                    //if (reader["id_localodad"].ToString() != null)
                   // { aux.Localidad = int.Parse(reader["id_localidad"].ToString()); }
                    //else { aux.Localidad = null; }


                    
                    
                    //************************Fin Formar objeto aux*********************
                    lista.Add(aux);
                    aux=null;
                }
                return lista;
            }
            catch(Exception ex)
            {
                 throw ex; //en caso que no pueda leer desde la base de datos tira el hacia la siguiente capa 
            }
            finally //finalmente cierro el reader que use para traer la consulta esto es importante ya que por alguna razon podria quedar abierto generando una conexion sin uso en la bd que estaria todo el tiempo abierta
            {
                closeReader(reader); //cierro el reader
                closecon();// cierra conexion

            }
        }

        public void Adicionar(EmpleadoMO item)
        {
            item.Codigo = getCodigoInsert("Empleado", "codigo");

            try
            {
                cmd = new SqlCommand(insert, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("@codigo", SqlDbType.Int).Value = item.Codigo;
                cmd.Parameters.Add("@nombre", SqlDbType.VarChar, 50).Value = item.Nombre;
                cmd.Parameters.Add("@apellido", SqlDbType.VarChar, 50).Value = item.Apellido;
                cmd.Parameters.Add("@teléfono",SqlDbType.VarChar,15).Value=item.Telefono;
                cmd.Parameters.Add("@tipoDocumento",SqlDbType.Int).Value=item.TipoDocumento;
                cmd.Parameters.Add("@nroDocumento",SqlDbType.Int).Value=item.NroDocumento;
                cmd.Parameters.Add("@codigoUsuario", SqlDbType.Int).Value = item.CodigoUsuario;
                cmd.Parameters.Add("@estado",SqlDbType.VarChar,10).Value=item.Estado;
                cmd.Parameters.Add("@calle",SqlDbType.VarChar,50).Value=item.Calle;
                cmd.Parameters.Add("@nro",SqlDbType.Int).Value=item.NroCalle;
                cmd.Parameters.Add("@piso",SqlDbType.VarChar,10).Value=item.Piso;
                cmd.Parameters.Add("@dpto",SqlDbType.VarChar,10).Value=item.Dpto;
                cmd.Parameters.Add("@id_localidad",SqlDbType.Int).Value=item.Localidad;


                


                opencon();
                cmd.ExecuteNonQuery();
                closecon();

            }
            catch (Exception ex)
            {
                closecon();
                throw ex;
            }
            
        }

        public void Eliminar(EmpleadoMO item)
        {
            try
            {
                cmd = new SqlCommand(delete, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("@codigo", SqlDbType.Int).Value = item.Codigo;

                opencon();
                cmd.ExecuteNonQuery();
                closecon();
            }
            catch (Exception ex)
            {
                closecon();
                throw ex;
            }

        }

        public void Actualizar(EmpleadoMO nuevoItem, EmpleadoMO origItem)
        {
            try
            {
                cmd = new SqlCommand(update, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("@codigo", SqlDbType.Int).Value = origItem.Codigo;
                cmd.Parameters.Add("@nombre", SqlDbType.VarChar, 50).Value = nuevoItem.Nombre;
                cmd.Parameters.Add("@apellido", SqlDbType.VarChar, 50).Value = nuevoItem.Apellido;
                cmd.Parameters.Add("@teléfono", SqlDbType.VarChar, 15).Value = nuevoItem.Telefono;
                cmd.Parameters.Add("@tipoDocumento", SqlDbType.Int).Value = nuevoItem.TipoDocumento;
                cmd.Parameters.Add("@nroDocumento", SqlDbType.Int).Value = nuevoItem.NroDocumento;
                cmd.Parameters.Add("@codigoUsuario", SqlDbType.Int).Value = nuevoItem.CodigoUsuario;
                cmd.Parameters.Add("@estado", SqlDbType.VarChar, 10).Value = nuevoItem.Estado;
                cmd.Parameters.Add("@calle", SqlDbType.VarChar, 50).Value = nuevoItem.Calle;
                cmd.Parameters.Add("@nro", SqlDbType.Int).Value = nuevoItem.NroCalle;
                cmd.Parameters.Add("@piso", SqlDbType.VarChar, 10).Value = nuevoItem.Piso;
                cmd.Parameters.Add("@dpto", SqlDbType.VarChar, 10).Value = nuevoItem.Dpto;
                cmd.Parameters.Add("@id_localidad", SqlDbType.Int).Value = nuevoItem.Localidad;
                
                opencon();
                cmd.ExecuteNonQuery();
                closecon();

            }
            catch (Exception ex)
            {
                closecon();
                throw ex;
            }

        }
        #endregion

        public DataTable reporteEmpleadoMasVentas(DateTime fecha, string ordena = "", string dire = "")
        {
            string sql = "";
            sql = "select top 1 t.codigo as 'Codigo',MAX(t.total) as 'Total',CONVERT(varchar(10) ,t.fecha,103) as 'Fecha', t.nombre 'Nombre', t.apellido as 'Apellido',t.teléfono as 'Telefono',t.tipoDocumento as 'Tipo de Documento',t.nroDocumento as 'Numero de Documento',t.direccion as 'Direccion' "
                        + "from ( "
                        + " SELECT f.codigoEmpleado as codigo,SUM(f.totalFactura) as total, f.fecha , e.nombre, e.apellido,e.teléfono,d.tipoDocumento,e.nroDocumento,((convert(varchar(50),isnull(e.calle,'-')))+' '+(convert(varchar(50),isnull(e.nro,'-')))+' '+(convert(varchar(50),isnull(e.piso,'')))+' '+(convert(varchar(50),isnull(e.dpto,'')))) as direccion, e.estado "
                        + " FROM Empleado e "
                        + " left join TipoDocumento d on e.tipoDocumento = d.codigo "
                        + " inner join Factura f on e.codigo = f.codigoEmpleado "
                        + " group by e.estado,f.fecha ,f.codigoEmpleado,e.nombre, e.apellido,e.teléfono,d.tipoDocumento,e.nroDocumento,((convert(varchar(50),isnull(e.calle,'-')))+' '+(convert(varchar(50),isnull(e.nro,'-')))+' '+(convert(varchar(50),isnull(e.piso,'')))+' '+(convert(varchar(50),isnull(e.dpto,'')))) ) t "
                        + " group by t.codigo,t.fecha,t.nombre,t.apellido,t.nroDocumento,t.tipoDocumento,t.direccion,t.teléfono, t.estado "
                        + " having t.estado = 'A' ";
                        
            try
            {
                DataTable dt = new DataTable();

                SqlCommand cmd = new SqlCommand();
                
                if (fecha != null)
                {
                    
                    sql += " and  t.fecha = @fecha";
                    cmd.Parameters.Add("@fecha", SqlDbType.DateTime).Value = fecha;
                }

                if (ordena != "")
                {

                    sql += " Order by " + ordena ;

                }
                if (dire != "")
                    sql += " " + dire;
                
                
                cmd.Connection =(getConexion());
                
                cmd.CommandText = sql;
                cmd.CommandType = CommandType.Text;
                SqlDataAdapter da = new SqlDataAdapter(cmd);

                opencon();
                da.Fill(dt);
                closecon();
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();
            }
        
        }
        public EmpleadoMO getByID(int codigo)
        {
            try
            {
                cmd = new SqlCommand(getXID, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add("@id", SqlDbType.Int).Value = codigo;

                opencon();
                SqlDataReader reader = cmd.ExecuteReader();
                EmpleadoMO aux = new EmpleadoMO();
                if (reader.Read())
                {

                    aux.Codigo = int.Parse(reader["codigo"].ToString());

                    if (reader["apellido"].ToString() != null)
                    { aux.Apellido = reader["apellido"].ToString(); }
                    else { aux.Apellido = ""; }

                    if (reader["nombre"].ToString() != null)
                    { aux.Nombre = reader["nombre"].ToString(); }
                    else { aux.Nombre = ""; }



                    if (reader["telefono"].ToString() != null)
                    { aux.Telefono = reader["telefono"].ToString(); }
                    else { aux.Telefono = ""; }

                    aux.TipoDocumento = int.Parse(reader["tipoDocumento"].ToString());

                    aux.NroDocumento = int.Parse(reader["nroDocumento"].ToString());

                    aux.CodigoUsuario = int.Parse(reader["nroDocumento"].ToString());


                    aux.Estado = reader["estado"].ToString();


                    aux.Calle = reader["calle"].ToString();


                    if (reader["nroCalle"].ToString() != null)
                    { aux.NroCalle = int.Parse(reader["nroCalle"].ToString()); }
                    else { aux.Calle = "0"; }

                    if (reader["piso"].ToString() != null)
                    { aux.Piso = reader["piso"].ToString(); }
                    else { aux.Piso = ""; }

                    if (reader["dpto"].ToString() != null)
                    { aux.Dpto = reader["dpto"].ToString(); }
                    else { aux.Dpto = ""; }


                    aux.Localidad = int.Parse(reader["id_localidad"].ToString());

                }

                reader.Close();
                closecon();
                return aux;
            }

            catch (SqlException ex)
            {
                closecon();
                throw new Exception("Error de Tipo SQL SERVER: " + ex.Message);
            }
            catch (Exception ex)
            {
                closecon();
                throw new Exception("Error Desconocido: " + ex.Message);
            }


        }


        public List<EmpleadoMO> getAllRegistrar()
        {
            SqlDataReader reader = null;
            List<EmpleadoMO> lista = new List<EmpleadoMO>();
            try
            {
                cmd = new SqlCommand(allRegistrar, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;
                opencon();
                reader = cmd.ExecuteReader();
                while (reader.Read())
                {
                    EmpleadoMO aux = new EmpleadoMO();
                    //****************************Formar objeto aux**********************
                    aux.Codigo = int.Parse(reader["codigo"].ToString());

                    if (reader["apellido"].ToString() != null)
                    { aux.Apellido = reader["apellido"].ToString(); }
                    else { aux.Apellido = ""; }

                    if (reader["nombre"].ToString() != null)
                    { aux.Nombre = reader["nombre"].ToString(); }
                    else { aux.Nombre = ""; }



                    if (reader["telefono"].ToString() != null)
                    { aux.Telefono = reader["telefono"].ToString(); }
                    else { aux.Telefono = ""; }

                    aux.TipoDocumento = int.Parse(reader["tipoDocumento"].ToString());

                    aux.NroDocumento = int.Parse(reader["nroDocumento"].ToString());

                    aux.CodigoUsuario = int.Parse(reader["nroDocumento"].ToString());


                    aux.Estado = reader["estado"].ToString();


                    aux.Calle = reader["calle"].ToString();


                    if (reader["nroCalle"].ToString() != null)
                    { aux.NroCalle = int.Parse(reader["nroCalle"].ToString()); }
                    else { aux.Calle = "0"; }

                    if (reader["piso"].ToString() != null)
                    { aux.Piso = reader["piso"].ToString(); }
                    else { aux.Piso = ""; }

                    if (reader["dpto"].ToString() != null)
                    { aux.Dpto = reader["dpto"].ToString(); }
                    else { aux.Dpto = ""; }


                    aux.Localidad = int.Parse(reader["id_localidad"].ToString());
                    //if (reader["id_localodad"].ToString() != null)
                    // { aux.Localidad = int.Parse(reader["id_localidad"].ToString()); }
                    //else { aux.Localidad = null; }




                    //************************Fin Formar objeto aux*********************
                    lista.Add(aux);
                    aux = null;
                }
                return lista;
            }
            catch (Exception ex)
            {
                throw ex; //en caso que no pueda leer desde la base de datos tira el hacia la siguiente capa 
            }
            finally //finalmente cierro el reader que use para traer la consulta esto es importante ya que por alguna razon podria quedar abierto generando una conexion sin uso en la bd que estaria todo el tiempo abierta
            {
                closeReader(reader); //cierro el reader
                closecon();// cierra conexion

            }
        }



    }


}
